/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.meanzoft.m3d.scene;

import java.util.LinkedList;
import org.lwjgl.util.vector.Vector3f;

/**
 *
 * @author Laptop
 */
public class SceneNode {

    /**
     * This nodes position (x,y,z)
     */
    public Vector3f position;
    /**
     * This node local translation (x,y,z)
     */
    public Vector3f localTranslation;
    /**
     * This node local scaling (x,y,z)
     */
    public Vector3f localScale;
    /**
     * This node local rotation
     */
    public float localPitch = 0f;
    public float localYaw = 0f;
    /**
     * This nodes children
     */
    private LinkedList<SceneNode> children;
    /**
     * Id
     */
    public Vector3f id = new Vector3f(0, 0, 0);

    public SceneNode() {
        position = new Vector3f(0.0f, 0.0f, 0.0f);
        localScale = new Vector3f(1f, 1f, 1f);
        children = new LinkedList<SceneNode>();
    }

    public SceneNode(Vector3f position) {
        this.position = position;
        localScale = new Vector3f(1f, 1f, 1f);
        children = new LinkedList<SceneNode>();
    }

    public SceneNode(Vector3f position, LinkedList<SceneNode> children) {
        this.position = position;
        localScale = new Vector3f(1f, 1f, 1f);
        this.children = children;
    }
    private int idX = 1, idY = 0, idZ = 0;
    public int selected = -1;

    /**
     * Adds a child to this node
     * @param child
     * The child to add
     * @return
     * Returns an index of this child
     */
    public int attach(SceneNode child) {
        children.add(child);
        idZ++;
        if (idZ == 128) {
            idZ = 0;
            idY++;
            if (idY == 128) {
                idY = 0;
                idX++;
                if (idX == 128) {
                    System.err.println("STAWK OWVERFLAWD");
                }
            }
        }
        child.id = new Vector3f(
                idX,
                idY,
                idZ);
        return children.indexOf(child);
    }

    /**
     * Removes a child from this node
     * @param child
     * The child reference to remo0ve
     * @return
     * Wheter the child was sucessfully removed or not
     */
    public boolean detatch(SceneNode child) {
        return children.remove(child);
    }

    /**
     * Removes a child from this node
     * @param childId
     * The child id to remove
     * @return
     * Wheter the child was sucessfully removed or not
     */
    public boolean detatch(int childId) {
        return children.remove(children.get(childId));
    }

    public void setPosition(Vector3f position) {
        this.position = position;
    }

    public Vector3f getPosition() {
        return position;
    }

    public void setLocalScale(Vector3f localScale) {
        this.localScale = localScale;
    }

    public void setLocalTranslation(Vector3f localTranslation) {
        this.localTranslation = localTranslation;
    }

    public LinkedList<SceneNode> getChildren() {
        return children;
    }
    /** ###################### **/
    /** ###################### **/
    /** ###################### **/
    /** Needs to be documented **/
    /** ###################### **/
    /** ###################### **/
    /** ###################### **/
    public float yaw = 0.0f;
    public float pitch = 0.0f;
    public float zRot = 0.0f;

    public void zRot(float amount) {
        zRot += amount;
    }

    public float getZRot() {
        return zRot;
    }

    public void setYaw(float amount) {
        yaw = amount;
    }

    public void yaw(float amount) {
        yaw += amount;
    }

    public float getYaw() {
        return yaw;
    }

    public void setPitch(float amount) {
        pitch = amount;
    }

    public void pitch(float amount) {
        pitch += amount;
    }

    public float getPitch() {
        return pitch;
    }

    public void moveForward(float distance) {
        position.x -= distance * (float) Math.sin(Math.toRadians(yaw));
        position.z += distance * (float) Math.cos(Math.toRadians(yaw));
        //position.y -= distance * (float) Math.sin(Math.toRadians(pitch));
    }

    public void moveBackwards(float distance) {
        position.x += distance * (float) Math.sin(Math.toRadians(yaw));
        position.z -= distance * (float) Math.cos(Math.toRadians(yaw));
        //position.y += distance * (float) Math.sin(Math.toRadians(pitch));
    }

    public void strafeLeft(float distance) {
        position.x -= distance * (float) Math.sin(Math.toRadians(yaw - 90));
        position.z += distance * (float) Math.cos(Math.toRadians(yaw - 90));
    }

    public void strafeRight(float distance) {
        position.x -= distance * (float) Math.sin(Math.toRadians(yaw + 90));
        position.z += distance * (float) Math.cos(Math.toRadians(yaw + 90));
    }
}
